package com.delistry.server;

import static com.delistry.server.PacketType.C_Packet;
import static com.delistry.server.clientpacket.ClientOpcodes.Sep;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Logger;

import com.delistry.server.clientpacket.ClientPacket;
import com.delistry.server.model.DeliverManager;
import com.delistry.server.utils.StreamUtil;

public class ClientProcess implements Runnable {
	private static Logger log = Logger.getLogger(ClientProcess.class.getName());

	private InputStream in;

	private OutputStream out;

	private Account account;

	private BufferedReader br;

	private PrintWriter wr;

	private final String ip;

	private final Socket csocket;

	public ClientProcess(Socket socket) {
		csocket = socket;
		ip = socket.getInetAddress().getHostAddress();
		try {
			in = csocket.getInputStream();
			out = csocket.getOutputStream();
			// 輸出入串流
			br = new BufferedReader(new InputStreamReader(in, "Unicode"));
			wr = new PrintWriter(new OutputStreamWriter(out, "Unicode"), true);

		} catch (Exception e) {
			System.out.println(e);
		}

	}

	@Override
	public void run() {
		log.info("(" + ip + ") connect to server.");

		// 背景封包作業
		while (!csocket.isClosed() && csocket.isConnected()) {
			int op = 0;
			String packet = "";
			try {
				packet = br.readLine();
				
				System.out.println(packet);
				
				op = Integer
						.valueOf(packet.split(Sep)[0]);
				
			} catch (NumberFormatException ne) {
				continue;
			} catch (IOException e) {
				e.printStackTrace();
			}

			DeliverManager.getInstance().HandlePacket(op,
					new ClientPacket(this, packet));
		}
		quite();

	}

	/**
	 * 處理斷線
	 */
	public void quite() {
		StreamUtil.close(in, out);
		try {
			csocket.close();

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		}
	}

	public void setAccount(Account account) {
		this.account = account;
	}

	public Account getAccount() {
		return this.account;
	}

	public String getAccountName() {
		if (account == null) {
			return null;
		}
		return account.getName();
	}

	public void close() throws IOException {
		csocket.close();
	}

	public Socket get_csocket() {
		return csocket;
	}

	public BufferedReader getBr() {
		return br;
	}

	public void setBr(BufferedReader br) {
		this.br = br;
	}

	public PrintWriter getWr() {
		return wr;
	}

	public void setWr(PrintWriter wr) {
		this.wr = wr;
	}

	public String getIp() {
		return ip;
	}

	public void SendClientPacket(String packet) {
		getWr().println(C_Packet + Sep + packet);
	}
}
